#include "../lvgl/lvgl.h"
#include "myMain.h"
//这里是客户端的

#define SERVER_IP "101.37.69.64"
#define PORT 5478
#define BUF_SIZE 65535
#define USER_JSON_FILE "userManagement.json"
#define BENDI_JSON_FILE "bendi.json"
#define SPEAK_JSON_FILE "speak.json"  // 新增speak文件定义

UserList *userList = NULL;
TrainList *trainList = NULL;
int g_server_socket = -1;
//套接字锁
pthread_mutex_t g_socket_mutex = PTHREAD_MUTEX_INITIALIZER;
//链表锁
pthread_mutex_t g_user_list_mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t g_train_list_mutex = PTHREAD_MUTEX_INITIALIZER; // 新增班次链表互斥锁
time_t g_user_last_modified = 0;
time_t g_bendi_last_modified = 0;
time_t g_speak_last_modified = 0;  // 新增speak文件最后修改时间

// 创建默认的JSON文件
void create_default_json_file(const char *filename, const char *default_content) 
{
    FILE *file = fopen(filename, "w");
    if (file) {
        fwrite(default_content, 1, strlen(default_content), file);
        fclose(file);
        printf("创建默认文件: %s\n", filename);
    } else {
        printf("无法创建文件: %s\n", filename);
    }
}

// 初始化JSON文件
void init_json_files() 
{
    struct stat st;
    
    // 检查并创建用户管理文件
    if (stat(USER_JSON_FILE, &st) != 0)
     {
        const char *default_user_content = "{\n"
            "    \"code\": 200,\n"
            "    \"checkCode\": \"userManagement\",\n"
            "    \"data\": []\n"
            "}";
        create_default_json_file(USER_JSON_FILE, default_user_content);
    }
    
    // 检查并创建班次管理文件
    if (stat(BENDI_JSON_FILE, &st) != 0) {
    const char *default_bendi_content =
        "{\n"
        "    \"code\": 200,\n"
        "    \"checkCode\": \"shiftManagement\",\n"
        "    \"data\": []\n"
        "}";
        create_default_json_file(BENDI_JSON_FILE, default_bendi_content);
    }
    
    // 检查并创建speak文件
    if (stat(SPEAK_JSON_FILE, &st) != 0) {
        const char *default_speak_content = "{\n"
            "    \"code\": 120,\n"
            "    \"send\": \"id\",\n"
            "    \"to\": \"id\",\n"
            "    \"message\": \"\"\n"
            "}";
        create_default_json_file(SPEAK_JSON_FILE, default_speak_content);
    }
}

// 读取JSON文件
int read_json_file(const char *filename, time_t *last_modified) 
{
    struct stat file_stat;
    if (stat(filename, &file_stat) != 0) 
    {
        printf("无法获取文件状态: %s\n", filename);
        return -1;
    }
    
    // 检查文件是否修改
    if (*last_modified == file_stat.st_mtime) 
    {
        return 0; // 文件未修改
    }
    
    *last_modified = file_stat.st_mtime;
    return 1; // 文件已修改
}

// 发送JSON数据到服务器
void send_json_data(int server_socket, const char *filename) 
{
    FILE *file = fopen(filename, "r");
    if (!file) {
        printf("无法打开JSON文件: %s\n", filename);
        return;
    }

    fseek(file, 0, SEEK_END);
    long length = ftell(file);
    fseek(file, 0, SEEK_SET);
    
    char *buffer = malloc(length + 1);
    if (!buffer) {
        fclose(file);
        return;
    }
    
    fread(buffer, 1, length, file);
    fclose(file);
    buffer[length] = '\0';
    
    cJSON *json_data = cJSON_Parse(buffer);
    free(buffer);
    
    if (!json_data) {
        printf("解析JSON失败: %s\n", filename);
        return;
    }
    
    cJSON *message = cJSON_CreateObject();
    cJSON_AddStringToObject(message, "filename", filename);
    cJSON_AddStringToObject(message, "action", "update");
    cJSON_AddItemToObject(message, "data", json_data);
    
    char *json_str = cJSON_Print(message);
    cJSON_Delete(message);
    
    if (json_str) 
    {
        // 添加消息长度前缀
        uint32_t message_length = strlen(json_str);
        uint32_t net_length = htonl(message_length);
        
        pthread_mutex_lock(&g_socket_mutex);
        if (g_server_socket != -1) {
            // 先发送消息长度
            send(g_server_socket, &net_length, sizeof(net_length), 0);
            // 再发送消息内容
            send(g_server_socket, json_str, message_length, 0);
            printf("发送文件到服务器: %s (长度: %u)\n", filename, message_length);
        }
        pthread_mutex_unlock(&g_socket_mutex);
        free(json_str);
    }
}

// 接收完整JSON消息
char* receive_json_message(int socket) 
{
    uint32_t message_length_net;
    int bytes_received = recv(socket, &message_length_net, sizeof(message_length_net), MSG_WAITALL);
    if (bytes_received != sizeof(message_length_net)) {
        printf("接收消息长度失败\n");
        return NULL;
    }
    
    uint32_t message_length = ntohl(message_length_net);
    if (message_length == 0 || message_length > 1024 * 1024) { // 限制最大1MB
        printf("无效的消息长度: %u\n", message_length);
        return NULL;
    }
    
    char *message = malloc(message_length + 1);
    if (!message) {
        printf("内存分配失败\n");
        return NULL;
    }
    
    bytes_received = recv(socket, message, message_length, MSG_WAITALL);
    if (bytes_received != message_length) {
        printf("接收消息内容失败，期望 %u 字节，实际 %d 字节\n", message_length, bytes_received);
        free(message);
        return NULL;
    }
    
    message[message_length] = '\0';
    return message;
}

// 处理服务器响应
void handle_server_response(cJSON *response) 
{
    cJSON *action = cJSON_GetObjectItem(response, "action");
    cJSON *filename = cJSON_GetObjectItem(response, "filename");
    cJSON *data = cJSON_GetObjectItem(response, "data");
    
    if (!action || !cJSON_IsString(action) || !filename || !cJSON_IsString(filename) || !data) 
    {
        printf("无效的服务器响应\n");
        return;
    }
    
    printf("处理服务器响应: action=%s, filename=%s\n", action->valuestring, filename->valuestring);
    
    if (strcmp(action->valuestring, "update") == 0) 
    {
        // 更新本地文件
        char *json_str = cJSON_Print(data);
        if (!json_str) {
            printf("无法格式化JSON数据\n");
            return;
        }
        
        FILE *file = fopen(filename->valuestring, "w");
        if (file) {
            fwrite(json_str, 1, strlen(json_str), file);
            fclose(file);
            
            // 更新修改时间
            struct stat file_stat;
            if (stat(filename->valuestring, &file_stat) == 0) {
                if (strcmp(filename->valuestring, USER_JSON_FILE) == 0) 
                {
                    g_user_last_modified = file_stat.st_mtime;
                    printf("更新用户管理文件\n");
                    
                    // 重新加载用户数据到链表
                    pthread_mutex_lock(&g_user_list_mutex);
                    if (userList) 
                    {
                        freeUserList(userList);
                    }
                    userList = initUserList();
                    if (userList) 
                    {
                        loadUsersFromFile(userList, USER_JSON_FILE);
                        printf("重新加载用户数据\n");
                    }
                    pthread_mutex_unlock(&g_user_list_mutex);
                } 
                else if (strcmp(filename->valuestring, BENDI_JSON_FILE) == 0) 
                {
                    g_bendi_last_modified = file_stat.st_mtime;
                    printf("更新班次管理文件\n");
                    
                    // 重新加载班次数据到链表
                    pthread_mutex_lock(&g_train_list_mutex);
                    if (trainList) 
                    {
                        freeTrainList(trainList);
                    }
                    trainList = initTrainList();
                    if (trainList) 
                    {
                        loadTrainsFromFile(trainList, BENDI_JSON_FILE);
                        printf("重新加载班次数据\n");
                    }
                    pthread_mutex_unlock(&g_train_list_mutex);
                }
                else if (strcmp(filename->valuestring, SPEAK_JSON_FILE) == 0) 
                {
                    g_speak_last_modified = file_stat.st_mtime;
                    printf("更新speak文件\n");
                    // 这里可以添加对speak文件的处理逻辑，如果需要的话
                }
            }
        } else {
            printf("无法打开文件用于写入: %s\n", filename->valuestring);
        }
        
        free(json_str);
    }
}

// 监控文件变化并发送更新
void *file_monitor_thread(void *arg) 
{
    while (1) {
        usleep(1000000); // 每5秒检查一次
        
        // 检查用户管理文件
        if (read_json_file(USER_JSON_FILE, &g_user_last_modified) == 1) 
        {
            printf("检测到用户管理文件变化\n");
            send_json_data(g_server_socket, USER_JSON_FILE);
        }
        
        // 检查班次管理文件
        if (read_json_file(BENDI_JSON_FILE, &g_bendi_last_modified) == 1) 
        {
            printf("检测到班次管理文件变化\n");
            send_json_data(g_server_socket, BENDI_JSON_FILE);
        }
        
        // 检查speak文件
        if (read_json_file(SPEAK_JSON_FILE, &g_speak_last_modified) == 1) 
        {
            printf("检测到speak文件变化\n");
            send_json_data(g_server_socket, SPEAK_JSON_FILE);
        }
    }
    
    return NULL;
}

// 请求服务器同步所有文件
void request_sync_from_server(int server_socket)
 {
    // 请求用户管理文件
    cJSON *request = cJSON_CreateObject();
    cJSON_AddStringToObject(request, "action", "sync");
    cJSON_AddStringToObject(request, "filename", USER_JSON_FILE);
    
    char *json_str = cJSON_Print(request);
    cJSON_Delete(request);
    
    if (json_str) 
    {
        // 添加消息长度前缀
        uint32_t message_length = strlen(json_str);
        uint32_t net_length = htonl(message_length);
        
        // 先发送消息长度
        send(server_socket, &net_length, sizeof(net_length), 0);
        // 再发送消息内容
        send(server_socket, json_str, message_length, 0);
        
        free(json_str);
    }
    
    // 请求班次管理文件
    request = cJSON_CreateObject();
    cJSON_AddStringToObject(request, "action", "sync");
    cJSON_AddStringToObject(request, "filename", BENDI_JSON_FILE);
    
    json_str = cJSON_Print(request);
    cJSON_Delete(request);
    
    if (json_str) 
    {
        // 添加消息长度前缀
        uint32_t message_length = strlen(json_str);
        uint32_t net_length = htonl(message_length);
        
        // 先发送消息长度
        send(server_socket, &net_length, sizeof(net_length), 0);
        // 再发送消息内容
        send(server_socket, json_str, message_length, 0);
        
        free(json_str);
    }
    
    // 请求speak文件
    request = cJSON_CreateObject();
    cJSON_AddStringToObject(request, "action", "sync");
    cJSON_AddStringToObject(request, "filename", SPEAK_JSON_FILE);
    
    json_str = cJSON_Print(request);
    cJSON_Delete(request);
    
    if (json_str) 
    {
        // 添加消息长度前缀
        uint32_t message_length = strlen(json_str);
        uint32_t net_length = htonl(message_length);
        
        // 先发送消息长度
        send(server_socket, &net_length, sizeof(net_length), 0);
        // 再发送消息内容
        send(server_socket, json_str, message_length, 0);
        
        free(json_str);
    }
}

// 服务器通信线程
void *server_communication_thread(void *arg) 
{
    struct sockaddr_in server_addr;
    
    // 创建socket
    if ((g_server_socket = socket(AF_INET, SOCK_STREAM, 0)) < 0) 
    {
        perror("socket creation failed");
        return NULL;
    }
    
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(PORT);
    
    // 转换IP地址
    if (inet_pton(AF_INET, SERVER_IP, &server_addr.sin_addr) <= 0) {
        perror("invalid address");
        close(g_server_socket);
        g_server_socket = -1;
        return NULL;
    }
    
    // 连接服务器
    if (connect(g_server_socket, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) 
    {
        perror("connection failed");
        close(g_server_socket);
        g_server_socket = -1;
        return NULL;
    }
    
    printf("已连接到服务器 %s:%d\n", SERVER_IP, PORT);
    
    // 请求服务器同步所有文件
    request_sync_from_server(g_server_socket);
    
    // 启动文件监控线程
    pthread_t monitor_thread;
    pthread_create(&monitor_thread, NULL, file_monitor_thread, NULL);
    
    // 处理服务器响应
    while (1) 
    {
        char *message = receive_json_message(g_server_socket);
        if (!message) {
            printf("接收消息失败，可能连接已断开\n");
            break;
        }
        
        cJSON *response = cJSON_Parse(message);
        free(message);
        
        if (response) {
            handle_server_response(response);
            cJSON_Delete(response);
        } else {
            printf("无法解析服务器响应\n");
        }
    }
    
    // 服务器断开连接
    pthread_mutex_lock(&g_socket_mutex);
    close(g_server_socket);
    g_server_socket = -1;
    pthread_mutex_unlock(&g_socket_mutex);
    
    pthread_cancel(monitor_thread);
    printf("与服务器的连接已断开\n");
    
    return NULL;
}


void myMain( void )
{
     // 初始化JSON文件
    init_json_files();
    
    // 初始化用户链表
    pthread_mutex_lock(&g_user_list_mutex);
    userList = initUserList();
    if(userList) 
    {
        // 从文件加载用户数据
        loadUsersFromFile(userList, "userManagement.json");
    }
    pthread_mutex_unlock(&g_user_list_mutex);

    // 班次链表初始化（现在也需要加锁）
    pthread_mutex_lock(&g_train_list_mutex);
    trainList = initTrainList();
    if (trainList)
    {
       loadTrainsFromFile(trainList, BENDI_JSON_FILE);
    }
    pthread_mutex_unlock(&g_train_list_mutex);

    // 获取初始文件修改时间
    struct stat file_stat;
    if (stat(USER_JSON_FILE, &file_stat) == 0) 
    {
        g_user_last_modified = file_stat.st_mtime;
    }
    if (stat(BENDI_JSON_FILE, &file_stat) == 0) 
    {
        g_bendi_last_modified = file_stat.st_mtime;
    }
    if (stat(SPEAK_JSON_FILE, &file_stat) == 0) 
    {
        g_speak_last_modified = file_stat.st_mtime;
    }

    loginUI();

     // 启动服务器通信线程
    pthread_t comm_thread;
    pthread_create(&comm_thread, NULL, server_communication_thread, NULL);
    
    // 主循环保持运行
    while(1) 
    {
        lv_tick_inc(5);
        lv_task_handler();
        usleep(5000);
    }
}